﻿using System;
using System.IO;
using Odin.Contracts.Data;
using Odin.Contracts.Services;
using Odin.Execution;

namespace Odin.Runners.CommandLine
{
	class Program
	{
		private static int returnCode;
		static int Main(string[] args)
		{
			if (!ArgumentManager.Instance.ValidateArguments(args))
			{
				ArgumentManager.Instance.ShowHelp();
				return -1;
			}
			ArgumentManager.Instance.ExecuteArguments(args);

			returnCode = 0;
			ShowLogo();
			RunTests();
			ShowFooter();
			return returnCode;
		}

		static void ShowLogo()
		{
			Console.WriteLine("Odin - CommandLine Silverlight Unit Test runner");
			Console.WriteLine("");
		}

		static void ShowSummary(Session session, TimeSpan totalTime)
		{
			var testsRun = 0;
			var failures = 0;
			var notRun = 0;

			foreach (var method in session.Methods)
			{
				testsRun++;
				switch (method.Result)
				{
					case Result.Failed:
					case Result.Inconlusive:
						{
							failures++;
						}
						break;
					case Result.NotRun:
						{
							notRun++;
						}
						break;
				}
			}

			Console.WriteLine("  Tests run: {0}, Failures: {1}, Not run: {2}, Time: {3}",
				testsRun,
				failures,
				notRun,
				totalTime);
		}

		static void ShowFooter()
		{

		}


		static void RunTests()
		{
			Console.WriteLine("Running tests - please wait");
			var before = DateTime.Now;
			if (!File.Exists(ArgumentManager.Instance.File))
			{
				Console.WriteLine("File \"{0}\" does not exist",ArgumentManager.Instance.File);
				return;
			}
			var session = Core.Instance.CreateSession(ArgumentManager.Instance.File, "App");

			session.MethodChanged += SessionMethodChanged;
			Core.Instance.RunSession(session);
			Core.Instance.WaitForCompletion(session);

			Core.Instance.EndSession(session);
			var configuration = Core.Kernel.Get<IConfiguration>();
			if (!configuration.WebServer.KeepServerAlive)
			{
				Core.Instance.ShutDown();
			}
			var after = DateTime.Now;

			var totalTime = after.Subtract(before);
			ShowSummary(session, totalTime);
		}

		static void SessionMethodChanged(Session session, Method method)
		{
			switch (method.Result)
			{
				case Result.Failed:
				case Result.Inconlusive:
					{
						returnCode = -1; // Failed
						Console.WriteLine("Method : {0}.{1}.{2} - {3}", method.Namespace, method.Class, method.MethodName, method.Result);
						if (null != method.Message)
						{
							Console.WriteLine("   Message : {0}", method.Message);
						}
						if (null != method.StackTrace)
						{
							Console.WriteLine("   StackTrace : {0}", method.StackTrace);
						}
						Console.WriteLine("\n\n");
					}
					break;
			}

		}
	}
}
